import { createStoreBindings } from "mobx-miniprogram-bindings";
import { globalStore } from "../../../store/index";
import { fetchMenu, updateMenu, toggleDishStatus } from "../../../services/dish";
import { submitOrder } from "../../../services/order";
import { toast } from "../../../utils/toast";
import { applyTabBar } from "../../../utils/tabBar";
import type { CategoryItem, MenuItem } from "../../../types/entities";

type CartMap = Record<string, number>;
type CartItemView = {
  menuId: string;
  name: string;
  funValue: number;
  coverUrl: string;
};
type CategoryOption = { key: string; name: string; icon?: string };

Page({
  data: {
    isChef: globalStore.isChef,
    loading: true,
    userProfile: globalStore.userProfile,
    categoryList: [] as Array<CategoryItem & { key: string }>,
    activeCategory: "all",
    menuList: [] as MenuItem[],
    filteredList: [] as MenuItem[],
    cartMap: {} as CartMap,
    cartCount: 0,
    cartItems: [] as CartItemView[],
    showCartPanel: false,
    submitLoading: false,
    inventoryCategories: [] as CategoryOption[],
    inventoryActive: "all",
    inventoryMenu: [] as MenuItem[],
    inventoryFiltered: [] as MenuItem[],
    showEditPanel: false,
    editingId: "",
    editingName: "",
    editStock: 0,
    editFunValue: 0,
    saving: false,
    displayedMenu: [] as MenuItem[],
  },

  storeBindings: null as WechatMiniprogram.Component.TrivialInstance | null,

  onLoad() {
    this.storeBindings = createStoreBindings(this, {
      store: globalStore,
      fields: ["categories", "menu", "cart", "userProfile", "isChef"],
      actions: ["setMenu", "setCart"],
    });
  },

  onUnload() {
    this.storeBindings?.destroyStoreBindings?.();
  },

  async onShow() {
    await globalStore.initAppData();
    const isChef = globalStore.isChef;
    this.setData({ isChef, userProfile: globalStore.userProfile });
    applyTabBar(isChef ? "chef" : globalStore.isDiner ? "diner" : "guest");
    await this.loadMenu();
    this.syncCategories();
    if (isChef) {
      this.setupInventory(globalStore.menu);
    } else {
      this.syncMenu(globalStore.menu);
      this.restoreCart();
    }
    this.updateDisplayedMenu();
  },

  async onPullDownRefresh() {
    await this.loadMenu();
    wx.stopPullDownRefresh();
  },

  async loadMenu() {
    this.setData({ loading: true });
    try {
      const res = await fetchMenu();
      globalStore.setMenu(res.menu);
      if (this.data.isChef) {
        this.setupInventory(res.menu);
      } else {
        this.syncMenu(res.menu);
        this.rebuildCartState(this.data.cartMap, true);
      }
      this.updateDisplayedMenu();
    } catch (error) {
      console.error("加载菜单失败", error);
      wx.showToast({ title: "加载失败", icon: "none" });
    } finally {
      this.setData({ loading: false });
    }
  },

  syncCategories() {
    const categories = globalStore.categories || [];
    const categoryList = [
      { key: "all", name: "全部", color: "#FFD7E2", icon: "🌈" },
      ...categories,
    ];
    this.setData({ categoryList });
  },

  syncMenu(menuList: MenuItem[]) {
    this.setData({ menuList }, () => {
      this.applyFilter(this.data.activeCategory || "all");
    });
  },

  applyFilter(categoryKey: string) {
    const source = this.data.menuList || [];
    const filtered =
      categoryKey === "all"
        ? source
        : source.filter((item) => item.categoryKey === categoryKey);
    this.setData({ activeCategory: categoryKey, filteredList: filtered }, () => {
      if (!this.data.isChef) {
        this.updateDisplayedMenu();
      }
    });
  },

  handleCategoryTap(event: WechatMiniprogram.BaseEvent) {
    const { key } = event.currentTarget.dataset as { key: string };
    if (this.data.isChef) {
      this.setData({ activeCategory: key });
      this.applyInventoryFilter(key);
      return;
    }
    this.applyFilter(key);
  },

  handleAddToCart(event: WechatMiniprogram.BaseEvent) {
    const { id, enabled } = event.currentTarget.dataset as { id: string; enabled?: boolean };
    if (this.data.isChef) {
      this.handleToggleStatus(id, !(enabled ?? true));
      return;
    }
    this.updateCartQuantity(id, 1);
  },

  handleDecreaseCart(event: WechatMiniprogram.BaseEvent) {
    if (this.data.isChef) return;
    const { id } = event.currentTarget.dataset as { id: string };
    this.updateCartQuantity(id, -1);
  },

  updateCartQuantity(menuId: string, delta: number) {
    if (!menuId) return;
    const menuItem = this.data.menuList.find((item) => item._id === menuId);
    if (!menuItem) {
      toast("菜品已下架");
      return;
    }
    if (!menuItem.isActive) {
      toast("菜品未上架");
      return;
    }
    if (menuItem.stock <= 0) {
      toast("今天售罄啦");
      return;
    }
    const cartMap: CartMap = { ...this.data.cartMap };
    const already = cartMap[menuId] ? 1 : 0;
    if (delta > 0) {
      if (already >= 1) {
        toast("已加入餐单");
        return;
      }
      cartMap[menuId] = 1;
    } else if (already) {
      delete cartMap[menuId];
    }
    this.rebuildCartState(cartMap, true);
    if (delta > 0) {
      toast("已加入餐单");
    }
  },

  rebuildCartState(cartMap: CartMap, syncStore = false) {
    if (this.data.isChef) return;
    const menuList = this.data.menuList || [];
    const nextMap: CartMap = {};
    const nextCart: { menuId: string; name: string; quantity: number; funValue: number }[] = [];
    const cartItems: CartItemView[] = [];

    Object.keys(cartMap).forEach((menuId) => {
      const menuItem = menuList.find((item) => item._id === menuId);
      if (!menuItem) {
        return;
      }
      const quantity = cartMap[menuId] ? 1 : 0;
      if (quantity <= 0 || menuItem.stock <= 0) {
        return;
      }
      nextMap[menuId] = 1;
      nextCart.push({
        menuId,
        name: menuItem.name,
        quantity,
        funValue: menuItem.funValue,
      });
      cartItems.push({
        menuId,
        name: menuItem.name,
        funValue: menuItem.funValue,
        coverUrl: menuItem.coverUrl,
      });
    });

    this.setData({
      cartMap: nextMap,
      cartCount: cartItems.length,
      cartItems,
      showCartPanel: cartItems.length ? this.data.showCartPanel : false,
    });

    if (syncStore) {
      globalStore.setCart(nextCart);
    }
  },

  restoreCart() {
    const cartMap: CartMap = {};
    (globalStore.cart || []).forEach((item) => {
      cartMap[item.menuId] = item.quantity;
    });
    this.rebuildCartState(cartMap, true);
  },

  setupInventory(menu: MenuItem[]) {
    const categories = new Map<string, CategoryOption>();
    menu.forEach((item) => {
      if (!categories.has(item.categoryKey)) {
        categories.set(item.categoryKey, this.decorateCategory(item.categoryKey));
      }
    });
    const categoryList: CategoryOption[] = [{ key: "all", name: "全部", icon: "🌈" }, ...Array.from(categories.values())];
    this.setData({
      inventoryCategories: categoryList,
      inventoryMenu: menu,
    });
    this.applyInventoryFilter(this.data.inventoryActive, menu);
  },

  decorateCategory(key: string): CategoryOption {
    const preset: Record<string, CategoryOption> = {
      stirfry: { key, name: "热炒", icon: "🍲" },
      rice: { key, name: "主食", icon: "🍚" },
      fruit: { key, name: "鲜果", icon: "🍉" },
      snack: { key, name: "小食", icon: "🍡" },
      whole: { key, name: "粗粮", icon: "🥖" },
      dessert: { key, name: "甜品", icon: "🍰" },
      drink: { key, name: "饮品", icon: "🧃" },
    };
    return preset[key] || { key, name: key, icon: "🥗" };
  },

  applyInventoryFilter(activeKey: string, menuList?: MenuItem[]) {
    const source = menuList ?? this.data.inventoryMenu;
    const filtered =
      activeKey === "all"
        ? source
        : source.filter((item) => item.categoryKey === activeKey);
    this.setData({
      inventoryActive: activeKey,
      inventoryFiltered: filtered,
    }, () => {
      if (this.data.isChef) {
        this.updateDisplayedMenu();
      }
    });
  },

  handleInventoryTab(event: WechatMiniprogram.BaseEvent) {
    const { key } = event.currentTarget.dataset as { key: string };
    this.applyInventoryFilter(key);
  },

  async handleToggleStatus(menuId: string, isActive: boolean) {
    try {
      const res = await toggleDishStatus(menuId, isActive);
      globalStore.updateMenuSnapshot(res.menu);
      toast(isActive ? "已上架" : "已下架");
      this.setupInventory(globalStore.menu);
    } catch (error) {
      console.error("更新状态失败", error);
      wx.showToast({ title: "操作失败", icon: "none" });
    }
  },

  handleOpenEdit(event: WechatMiniprogram.BaseEvent) {
    if (!this.data.isChef) return;
    const { id } = event.currentTarget.dataset as { id: string };
    const target = this.data.inventoryMenu.find((item) => item._id === id);
    if (!target) return;
    this.setData({
      showEditPanel: true,
      editingId: target._id,
      editingName: target.name,
      editStock: target.stock,
      editFunValue: target.funValue,
    });
  },

  handleCloseEdit() {
    this.setData({ showEditPanel: false, editingId: "" });
  },

  handleStep(event: WechatMiniprogram.BaseEvent) {
    const { type, delta } = event.currentTarget.dataset as { type: "stock" | "fun"; delta: "inc" | "dec" };
    const step = delta === "dec" ? -1 : 1;
    if (type === "stock") {
      this.setData({ editStock: Math.max(0, this.data.editStock + step) });
    } else {
      this.setData({ editFunValue: Math.max(0, this.data.editFunValue + step) });
    }
  },

  handleStockInput(event: WechatMiniprogram.CustomEvent<{ value: string }>) {
    const value = Math.max(0, Number(event.detail.value || 0));
    this.setData({ editStock: value });
  },

  handleFunInput(event: WechatMiniprogram.CustomEvent<{ value: string }>) {
    const value = Math.max(0, Number(event.detail.value || 0));
    this.setData({ editFunValue: value });
  },

  async handleSaveEdit() {
    if (!this.data.editingId || this.data.saving) return;
    this.setData({ saving: true });
    try {
      const res = await updateMenu({
        _id: this.data.editingId,
        stock: this.data.editStock,
        funValue: this.data.editFunValue,
      });
      globalStore.updateMenuSnapshot(res.menu);
      toast("已更新库存");
      this.handleCloseEdit();
      this.setupInventory(globalStore.menu);
    } catch (error) {
      console.error("更新库存失败", error);
      wx.showToast({ title: "保存失败", icon: "none" });
    } finally {
      this.setData({ saving: false });
    }
  },

  handleGoCart() {
    if (this.data.isChef) {
      wx.switchTab({ url: "/pages/user/cart/index" });
    }
  },

  handleToggleCartPanel() {
    if (this.data.isChef) return;
    if (!this.data.cartCount) {
      toast("先挑几道菜吧");
      return;
    }
    this.setData({ showCartPanel: !this.data.showCartPanel });
  },

  handleRemoveCartItem(event: WechatMiniprogram.BaseEvent) {
    if (this.data.isChef) return;
    const { id } = event.currentTarget.dataset as { id: string };
    if (!id) return;
    const cartMap: CartMap = { ...this.data.cartMap };
    if (cartMap[id]) {
      delete cartMap[id];
      this.rebuildCartState(cartMap, true);
    }
  },

  async handleSubmitCart() {
    if (this.data.isChef || this.data.submitLoading) return;
    if (!this.data.cartItems.length) {
      toast("请先选择菜品");
      return;
    }
    this.setData({ submitLoading: true });
    try {
      const payload = {
        items: this.data.cartItems.map((item) => ({
          menuId: item.menuId,
          quantity: 1,
        })),
      };
      const res = await submitOrder(payload);
      globalStore.clearCart();
      this.rebuildCartState({}, true);
      this.setData({ showCartPanel: false });
      toast("已提交订单");
      setTimeout(() => {
        wx.switchTab({ url: "/pages/user/cart/index" });
      }, 300);
      if (res?.order) {
        globalStore.updateOrderSnapshot(res.order);
      }
    } catch (error) {
      console.error("提交订单失败", error);
      toast((error as Error).message || "提交失败");
    } finally {
      this.setData({ submitLoading: false });
    }
  },

  updateDisplayedMenu() {
    if (this.data.isChef) {
      this.setData({ displayedMenu: this.data.inventoryFiltered });
    } else {
      this.setData({ displayedMenu: this.data.filteredList });
    }
  },
});
